package com.example.demo.services;

import com.example.demo.entites.GlobalNum;
import com.example.demo.entites.RegionStats;
import lombok.Data;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Data
public class CSVServices implements InitializingBean {
    @Value("${Resource.User_Agent}")
    private String User_Agent;
    @Value("${Resource.URL}")
    private String URL;

    private List<RegionStats> regionStatsList = new ArrayList<>();

    private GlobalNum globalNum = new GlobalNum();

    public List<CSVRecord> getCSVRecordsByURL(String url) throws IOException {

        RequestEntity<Void> requestEntity = RequestEntity
                .get(URI.create(url))
                .headers(httpHeaders -> httpHeaders.add("User-Agent", User_Agent))
                .build();
        ResponseEntity<Resource> exchange = new RestTemplate().exchange(requestEntity, Resource.class);


        Resource body = exchange.getBody();
        Reader in = new InputStreamReader(body.getInputStream());
        CSVFormat csvFileFormat = CSVFormat.DEFAULT.withHeader();
        CSVParser csvFileParser = new CSVParser(in, csvFileFormat);
        return csvFileParser.getRecords();
    }



//    获取全球实时确诊人数
    @Scheduled(cron = "${Resource.updateVirusDataCron}")
    public void fetchAllConfirmedRecords() throws IOException {

        List<CSVRecord> csvRecords = getCSVRecordsByURL(URL);
        regionStatsList = csvRecords.stream()
                .map(record -> {
                    int latestTotalCases = Integer.parseInt(record.get(record.size()-1));
                    int preDayTotalCases = Integer.parseInt(record.get(record.size()-2));
                    int diffFromPrevDay = latestTotalCases-preDayTotalCases;
                    globalNum.totalConfirm += latestTotalCases;
                    globalNum.diffFromPrevDayConfirm += diffFromPrevDay;
                    return RegionStats.builder()
                            .state(record.get(0))
                            .country(record.get(1))
                            .latestTotalCaes(latestTotalCases)
                            .diffFromPrevDay(diffFromPrevDay)
                            .build();
                }).collect(Collectors.toList());
        Collections.sort(regionStatsList);

    }

    public List<RegionStats> fetchCountryConfirmedRecords(String country) throws IOException {

        List<RegionStats> countryList = new ArrayList<>();
        for (RegionStats r : regionStatsList) {
            if (r.getCountry().toUpperCase().equals(country)) {
                countryList.add(r);
            }
        }
        return countryList;

    }
//    spring容器初始化的时候，如果bean实现InitializingBean，会调用afterPropertiesSet方法
//    即可实现在spring初始化后，将确诊数据实例化放入内存中
    public void afterPropertiesSet() throws Exception {
        fetchAllConfirmedRecords();
    }
}
